    import java.awt.*;
    import java.awt.event.*;
    import java.net.*;
    import java.io.*;
    import java.util.*;

    public class test extends Frame implements ActionListener, WindowListener {

    //*****  Mulit-threaded client, sends and receives multiple messages
    //       expected to connect to server on hawk-cs.cs.unc.edu:8901


    protected String DEFAULT_HOST = "hawk-cs.cs.unc.edu";
    protected int DEFAULT_PORT = 8901;
    String host;
    int port;

    ConnectServer connection;

    TextField hostDisplay, portDisplay;
    TextArea logDisplay, msgDisplay;
    Panel topPanel;
    Panel middlePanel;
    Panel buttonPanel;
    Button connectButton, sendButton, cancelButton, quitButton;


    // **************  test

        public test ()  {

            super ( "test " );
            buildUI ();

        }  // end constructor


    // **************  main

        public static void main ( String [ ] args )  {

            test client = new test ();

        }  // end main


    //***********  Interface Methods   ***********


    //****  ActionListener methods

      public void actionPerformed ( ActionEvent e )  {

        Object s = e.getSource();

        // *** process Button actions

        if ( s instanceof Button )  {

            if ( s == connectButton )  {
                connection = new ConnectServer ( this );
                connection.start ();
            }  // end connectButton

            if ( s == sendButton )  {
                connection.sendReceive ();
            }  // end sendButton

            if ( s == cancelButton )  {
                msgDisplay.setText ( "" );
            }  // end cancelButton

            if ( s == quitButton )  {
                logDisplay.appendText ( "Closing connection and quitting\n" );
                connection.closeConnection ();
                try {Thread.sleep ( 2000 );} catch ( InterruptedException except) {;}

                hide ();
                dispose ();
                System.exit ( 0 );

                }  // end quitButton

        }  // end process Button actions

      }  // end actionPerformed


    //****  WindowListener methods

      public void windowActivated ( WindowEvent e )  {
      }

      public void windowDeactivated ( WindowEvent e )  {
      }

      public void windowOpened ( WindowEvent e )  {
      }

       public void windowClosed ( WindowEvent e )  {
      }

      public void windowClosing ( WindowEvent e )  {
        hide ();
        dispose ();
        System.exit(0);
      }

      public void windowIconified ( WindowEvent e )  {
      }

      public void windowDeiconified ( WindowEvent e )  {
      }


    //***********  Utility Methods   ***********


    // **************  buildUI

      private void buildUI ()  {

        try {
            InetAddress here = InetAddress.getLocalHost ();
            host = here.getHostName ();
        }
        catch (UnknownHostException e) { ;}

        hostDisplay = new TextField ( host, 30 );
        portDisplay = new TextField ( Integer.toString ( DEFAULT_PORT ), 4 );
        topPanel = new Panel ();
        topPanel.setLayout ( new GridLayout ( 2, 1 ) );
        topPanel.add ( hostDisplay );
        topPanel.add ( portDisplay );

        logDisplay = new TextArea ( 40, 10 );
        msgDisplay = new TextArea ( 40, 10 );
        msgDisplay.setText ("Default message.");
        middlePanel = new Panel ();
        middlePanel.setLayout ( new GridLayout ( 2, 1 ) );
        middlePanel.add ( logDisplay );
        middlePanel.add ( msgDisplay );

        connectButton = new Button ( "Connect" );
        sendButton = new Button ( "Send" );
        cancelButton = new Button ( "Cancel" );
        quitButton = new Button ( "Quit" );
        connectButton.addActionListener ( this );
        sendButton.addActionListener ( this );
        cancelButton.addActionListener ( this );
        quitButton.addActionListener ( this );
        buttonPanel = new Panel ( );
        buttonPanel.add ( connectButton );
        buttonPanel.add ( sendButton );
        buttonPanel.add ( cancelButton );
        buttonPanel.add ( quitButton );

        add ( "North", topPanel );
        add ( "Center", middlePanel );
        add ( "South", buttonPanel );

        resize ( 400, 450 );
        show ();

        }  // end buildUI


    }  // end Server_Threaded



    // ************************  ConnectServer Class ************************



    class ConnectServer extends Thread  {

    test source;

    String host;
    int port;
    Socket connection;

    InputStream inStream;
    DataInputStream inDataStream;
    OutputStream outStream;
    DataOutputStream outDataStream;

    String message;

    public static final String DEFAULT_HOST = "hawk-cs.cs.unc.edu";
    public static final int DEFAULT_PORT = 8901;


    // **************  ConnectServer

        ConnectServer ( test c)  {

            super ();

            source = (test ) c;

            connectServer ();

        }  // end constructor


    // **************  run

        public void run  ()  {

        }  // end run


    // **************  connectServer

      public void connectServer (  )  {

        host = source.hostDisplay.getText ();
        if ( host.equals ("" ) ) host = source.DEFAULT_HOST;
        if ( ! ( source.portDisplay.getText () ).equals ( "" ) ) port = Integer.parseInt ( source.portDisplay.getText () );
        else port = source.DEFAULT_PORT;

        try  {
          connection = new Socket ( host, port );

          outStream = connection.getOutputStream ();
          outDataStream = new DataOutputStream ( outStream );
          inStream = connection.getInputStream ();
          inDataStream = new DataInputStream ( inStream );

          source.logDisplay.setText ( "Socket created: \n  connecting to server "+host+":"+port+"\n\n" );

        }  // end try

        catch ( IOException except)  {
          source.logDisplay.setText ( "Error connecting to server\n" );
          except.printStackTrace ();
          System.exit ( 1 );
        }  // end catch

      }  // end connectServer


    // **************  sendReceive

      public void sendReceive ()  {

        try {

            message = source.msgDisplay.getText ();
            outDataStream.writeUTF ( message );
            source.logDisplay.appendText ( "Message, below, sent to Server\n" );

            source.msgDisplay.setText ( "" );
            source.msgDisplay.setForeground ( Color.red );

            message = inDataStream.readUTF ();
            source.msgDisplay.appendText ( message );
            source.logDisplay.appendText ( "  Message returned from server\n\n" );

        }  // end try for input

        catch ( EOFException except ) {
            source.logDisplay.appendText ( "EOF received\n" );
            closeConnection ();
        }  // end catch IOException
        catch ( IOException e )  {
            source.logDisplay.appendText ( "IOException\n" );
            e.printStackTrace ();
            return;
        }  // end catch IOException

      }  // end sendReceive


    // **************  closeConnection

      public void closeConnection () {

        try {
          connection.close ();
         }  catch ( IOException except )  {
            source.logDisplay.appendText ( "  Error clossing conncetion\n" );
           except.printStackTrace ();
         }

      }  // end closeConnection


    }  // end ConnectServer

